Add copilot support. Courtesy Paul Tomblin.
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 9 Apr 2003 13:09:36 +0000 (13:09 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 9 Apr 2003 13:09:36 +0000 (13:09 +0000)
gpsbabel/Makefile
gpsbabel/README
gpsbabel/copilot.c [new file with mode: 0644]
gpsbabel/defs.h
gpsbabel/jeeps/gpsmath.c
gpsbabel/util.c
gpsbabel/vecs.c

index 81de1b0f4cdc925584d461c07586e9bf48f06034..430606fdd8d7efc7fd1cb3e27491aa5308aa5a24 100644 (file)
@@ -3,7 +3,7 @@ CFLAGS=$(EXTRA_CFLAGS) -g -Icoldsync
 INSTALL_TARGETDIR=/usr/local/
 
 FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o \
-       gpsutil.o pcx.o cetus.o gpspilot.o magnav.o \
+       gpsutil.o pcx.o cetus.o copilot.o gpspilot.o magnav.o \
        psp.o holux.o garmin.o tmpro.o tpg.o \
        xcsv.o gcdb.o tiger.o internal_styles.o
 
@@ -70,6 +70,7 @@ release:
        ncftpput -u anonymous upload.sf.net  /incoming /tmp/gpsbabel-$(VERSIOND).tar.gz /tmp/gpsbabel-$(VERSIOND).zip
 
 cetus.o: cetus.c defs.h queue.h coldsync/palm.h coldsync/pdb.h
+copilot.o: copilot.c defs.h queue.h coldsync/palm.h coldsync/pdb.h
 csv.o: csv.c defs.h queue.h csv_util.h
 csv_util.o: csv_util.c defs.h queue.h csv_util.h
 dna.o: dna.c defs.h queue.h csv_util.h
index 031af367015ae6c14137c21c6e1b675db0b75984..0db94a67977927cc19cbf3a7ff96b47403ebd9fc 100644 (file)
@@ -293,6 +293,19 @@ THE FORMATS
 
        http://vip.hyperusa.com/~dougs/geocachingdb/geocachingdb.htm
 
+    CoPilot Flight Planner for Palm OS
+
+        This code is mostly intended to convert CoPilot databases into
+        other formats.  I don't think you should use this to write
+        CoPilot databases, although the code is there, mostly because
+        GPSBabel doesn't convert magnetic declination values.
+
+        Questions, bug reports, etc, to ptomblin at xcski.com
+
+
+       http://xcski.com/~ptomblin/CoPilot/
+       http://navaid.com/CoPilot/
+
 
 DATA FILTERS
 
diff --git a/gpsbabel/copilot.c b/gpsbabel/copilot.c
new file mode 100644 (file)
index 0000000..f36a321
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+    Read and write CoPilot files.
+
+    Copyright (C) 2002 Paul Tomblin, ptomblin@xcski.com
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include "coldsync/palm.h"
+#include "coldsync/pdb.h"
+#include "math.h"
+#ifndef M_PI
+#define M_PI 3.14159265358979323846 
+#endif
+
+static double conv = 180.0 / M_PI;
+
+#define MYNAME         "CoPilot Waypoint"
+#define MYTYPE                 0x77617970      /* wayp */
+#define MYCREATOR      0x47584255              /* GXBU */
+
+
+struct record {
+       pdb_double      latitude;       /* PDB double format, */
+       pdb_double      longitude;      /* similarly, neg = east */
+       pdb_double      magvar;         /* magnetic variation in degrees, neg = east */
+       pdb_double      elevation;      /* feet */
+       char            flags;
+};
+
+static FILE *file_in;
+static FILE *file_out;
+static const char *out_fname;
+struct pdb *opdb;
+struct pdb_record *opdb_rec;
+
+static void
+rd_init(const char *fname, const char *args)
+{
+       file_in = fopen(fname, "rb");
+       if (file_in == NULL) {
+               fatal(MYNAME ": Cannot open %s for reading\n", fname);
+       }
+}
+
+static void
+rd_deinit(void)
+{
+       fclose(file_in);
+}
+
+static void
+wr_init(const char *fname, const char *args)
+{
+       file_out = fopen(fname, "wb");
+       out_fname = fname;
+       if (file_out == NULL) {
+               fatal(MYNAME ": Cannot open %s for writing\n", fname);
+       }
+}
+
+static void
+wr_deinit(void)
+{
+       fclose(file_out);
+}
+
+static void
+data_read(void)
+{
+       struct record *rec;
+       struct pdb *pdb;
+       struct pdb_record *pdb_rec;
+
+       if (NULL == (pdb = pdb_Read(fileno(file_in)))) {
+               fatal(MYNAME ": pdb_Read failed\n");
+       }
+
+       if ((pdb->creator != MYCREATOR) || (pdb->type != MYTYPE)) {
+               fatal(MYNAME ": Not a CoPilot file.\n");
+       }
+
+       for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) {
+               waypoint *wpt_tmp;
+               char *vdata;
+
+               wpt_tmp = xcalloc(sizeof(*wpt_tmp),1);
+
+               rec = (struct record *) pdb_rec->data;
+               wpt_tmp->position.longitude.degrees =
+                 -pdb_read_double(&rec->longitude) * conv;
+               wpt_tmp->position.latitude.degrees =
+                 pdb_read_double(&rec->latitude) * conv;
+               wpt_tmp->position.altitude.altitude_meters =
+                 pdb_read_double(&rec->elevation) * .3048;
+
+               vdata = (char *) pdb_rec->data + sizeof(*rec);
+
+               wpt_tmp->shortname = xstrdup(vdata);
+               vdata = vdata + strlen(vdata) + 1;
+
+               wpt_tmp->description = xstrdup(vdata);
+               vdata = vdata + strlen(vdata) + 1;
+               
+               wpt_tmp->notes = xstrdup(vdata);
+
+               waypt_add(wpt_tmp);
+
+       } 
+       free_pdb(pdb);
+}
+
+
+static void
+copilot_writewpt(const waypoint *wpt)
+{
+       struct record *rec;
+       static int ct = 0;
+       char *vdata;
+
+       rec = xcalloc(sizeof(*rec)+1141,1);
+
+       pdb_write_double(&rec->latitude, wpt->position.latitude.degrees / conv);
+       pdb_write_double(&rec->longitude,
+               -wpt->position.longitude.degrees / conv);
+       pdb_write_double(&rec->elevation,
+               wpt->position.altitude.altitude_meters / .3048);
+       pdb_write_double(&rec->magvar, 0);
+
+       vdata = (char *)rec + sizeof(*rec);
+       if ( wpt->shortname ) {
+                         strncpy( vdata, wpt->shortname, 10 );
+                         vdata[9] = '\0';
+       }
+       else {
+                         vdata[0] ='\0';
+       }
+    vdata += strlen( vdata ) + 1;
+       if ( wpt->description ) {
+                       strncpy( vdata, wpt->description, 100 );
+                       vdata[99] = '\0';
+       }
+       else {
+                       vdata[0] ='\0';
+       }
+       vdata += strlen( vdata ) + 1;
+       
+       if ( wpt->notes ) {
+                       strncpy( vdata, wpt->notes, 1000 );
+                       vdata[999] = '\0';
+       }
+       else {
+                       vdata[0] ='\0';
+       }
+       vdata += strlen( vdata ) + 1;
+
+       opdb_rec = new_Record (0, 2, ct++, vdata-(char *)rec, (const ubyte *)rec);             
+
+       if (opdb_rec == NULL) {
+               fatal(MYNAME ": libpdb couldn't create record\n");
+       }
+
+       if (pdb_AppendRecord(opdb, opdb_rec)) {
+               fatal(MYNAME ": libpdb couldn't append record\n");
+       }
+       xfree(rec);
+}
+
+static void
+data_write(void)
+{
+       queue *elem, *tmp;
+
+       if (NULL == (opdb = new_pdb())) { 
+               fatal (MYNAME ": new_pdb failed\n");
+       }
+
+       strncpy(opdb->name, out_fname, PDB_DBNAMELEN);
+       opdb->name[PDB_DBNAMELEN-1] = 0;
+       opdb->attributes = PDB_ATTR_BACKUP;
+       opdb->ctime = opdb->mtime = time(NULL) + 2082844800U;
+       opdb->type = MYTYPE;
+       opdb->creator = MYCREATOR; 
+       opdb->version = 0;
+
+       waypt_disp_all(copilot_writewpt);
+       
+       pdb_Write(opdb, fileno(file_out));
+}
+
+
+ff_vecs_t copilot_vecs = {
+       rd_init,
+       wr_init,
+       rd_deinit,
+       wr_deinit,
+       data_read,
+       data_write,
+};
index 5107b2dc52e3521569d66d5fb28c462d7d353199..77970284f12f910bb85899b6d12a44137a258db1 100644 (file)
@@ -344,6 +344,10 @@ typedef struct {
        unsigned char data[2];
 } pdb_16;
 
+typedef struct {
+       unsigned char data[8];
+} pdb_double;
+
 /*
  * Protypes for Endianness helpers.
  */
@@ -356,6 +360,8 @@ void be_write16(void *pp, unsigned i);
 void be_write32(void *pp, unsigned i);
 void le_write16(void *pp, unsigned i);
 void le_write32(void *pp, unsigned i);
+double pdb_read_double(void *p);
+void pdb_write_double(void *pp, double d);
 
 /*
  * A constant for unknown altitude.   It's tempting to just use zero
index 35e9da385f705a2070896c9a127a3d45bec703a4..c5c623335aa78e8a784aa22f2199c40b076638b5 100644 (file)
@@ -217,7 +217,7 @@ void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg)
 
 double GPS_Math_Metres_To_Feet(double v)
 {
-    return v*(double)2.7432;
+    return v/0.3048;
 }
 
 
@@ -233,7 +233,7 @@ double GPS_Math_Metres_To_Feet(double v)
 
 double GPS_Math_Feet_To_Metres(double v)
 {
-    return v/(double)2.7432;
+    return v * 0.3048;
 }
 
 
index de40fc3441173577fca0e6ba4549375efe79d058..359e6f2c2d6486b0e42499f093380b56b56d81a8 100644 (file)
@@ -372,3 +372,54 @@ get_cache_icon(const waypoint *waypointp)
        }
        return NULL;
 }
+
+static int swapit = -1;
+
+static int doswap()
+{
+  if (swapit < 0)
+  {
+       /*      On Intel, Vax and MIPs little endian, -1.0 maps to the bytes
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f and on Motorola,
+               SPARC, ARM, and PowerPC, it maps to
+               0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00.
+       */
+       double d = 1.0;
+       char c[8];
+       memcpy(c, &d, 8);
+       swapit = (c[0] == 0);
+  }
+  return swapit;
+}
+
+double
+pdb_read_double(void* ptr)
+{
+  double ret;
+  char r[8];
+  int i;
+  doswap(); /* make sure swapit is initialized */
+  for (i = 0; i < 8; i++)
+  {
+       int j = (swapit)?(7-i):i;
+       r[i] = ((char*)ptr)[j];
+  }
+  memcpy(&ret, r, 8);
+  return ret;
+}
+
+void
+pdb_write_double(void* ptr, double d)
+{
+  char r[8];
+  int i;
+
+  memcpy(r, &d, 8);
+  doswap(); /* make sure swapit is initialized */
+  for (i = 0; i < 8; i++)
+  {
+       int j = (swapit)?(7-i):i;
+       *(char*)ptr++ = r[j];
+  }
+  return;
+}
index 9db8180ee2cec9f870ea19d94853cca8f7dc8526..c67cff2c9352108a3f17ab1c2bcfb54053c24bf1 100644 (file)
@@ -40,6 +40,7 @@ extern ff_vecs_t tiger_vecs;
 extern ff_vecs_t pcx_vecs;
 extern ff_vecs_t cetus_vecs;
 extern ff_vecs_t gpspilot_vecs;
+extern ff_vecs_t copilot_vecs;
 extern ff_vecs_t psp_vecs;
 extern ff_vecs_t garmin_vecs;
 extern ff_vecs_t holux_vecs;
@@ -112,6 +113,12 @@ vecs_t vec_list[] = {
                "Cetus for Palm/OS", 
                NULL
        },
+       {
+               &copilot_vecs,
+               "copilot",
+               "CoPilot Flight Planner for Palm/OS", 
+               NULL
+       },
        {
                &gpspilot_vecs,
                "gpspilot",